package top.huxy.boot.config.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import top.huxy.boot.annotation.NoRecordRequest;
import top.huxy.boot.config.Constant;
import top.huxy.boot.model.entity.Admin;
import top.huxy.boot.model.entity.User;
import top.huxy.boot.util.StringUtils;
import top.huxy.boot.util.obj.ThreadLocalAdmin;
import top.huxy.boot.util.obj.ThreadLocalRequestDetail;
import top.huxy.boot.util.obj.ThreadLocalRequestStartTime;
import top.huxy.boot.util.obj.ThreadLocalUser;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @Classname ThreadLocalInitializeInterceptor
 * @Description ThreadLocalInitializeInterceptor
 * @Date 2021/9/24 18:28
 * @Created by huxy
 */
public class ThreadLocalInitializeInterceptor implements HandlerInterceptor {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        ThreadLocalRequestStartTime.init();

        //初始化一些变量。如User，Admin
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if (Constant.ADMIN_TOKEN_NAME.equals(name)) {
                    String token = cookie.getValue();
                    if (StringUtils.isEmpty(token)) {
                        continue;
                    }
                    Object admin = redisTemplate.opsForValue().get(token);
                    if (admin == null) {
                        continue;
                    }

                    if (admin instanceof Admin) {
                        request.setAttribute(Constant.ADMIN_ATTRIBUTE_NAME, admin);
                        //管理员登录成功，延续一天登录有效期
                        redisTemplate.expire(token, 1L, TimeUnit.DAYS);
                        ThreadLocalAdmin.setCurrentAdmin((Admin) admin);
                    }
                } else if (Constant.USER_TOKEN_NAME.equals(name)) {
                    String token = cookie.getValue();
                    if (StringUtils.isEmpty(token)) {
                        continue;
                    }
                    Object user = redisTemplate.opsForValue().get(token);
                    if (user == null) {
                        continue;
                    }

                    if (user instanceof User) {
                        request.setAttribute(Constant.USER_ATTRIBUTE_NAME, user);
                        ThreadLocalUser.setCurrentUser((User) user);
                    }
                }

            }
        }

        HandlerMethod methodHandler = (HandlerMethod) handler;

        if (!methodHandler.hasMethodAnnotation(NoRecordRequest.class)) {
            //初始化请求详情
            ThreadLocalRequestDetail requestDetail = new ThreadLocalRequestDetail(request, methodHandler);
            ThreadLocalRequestDetail.setLocalRequestDetail(requestDetail);
        }

        return true;
    }
}
